﻿using ParticeInClass;
using System;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using static HomeWork.Captcha;
using static HomeWork.TokenManager;
using static HomeWork.User;
using static System.Formats.Asn1.AsnWriter;

namespace HomeWork
{
    public class NewProgram
    {
        static void Main(String[] args)
        {
            //2、声明一个方法encourage()，传入两个参数：
            //    origin：用户原有的积分（帮帮点）
            //    rank：用户的等级
            //方法能使用switch...case和枚举：
            //    根据用户的等级，在用户原有积分上给予不同的加分，
            //    输出“一起帮周年庆，系统根据你的等级为你自动奖励X分”，
            //    返回加分后的结果

            //3、修改encourage()方法，“单叶”和“双叶”都加一样的分
            //User jiang = new User();
            //int origin =  User.Encourage(jiang.origin, User.Rank.Newbie);
            //int origin = User.Encourage(jiang.origin, User.Rank.Veteran);
            //int origin = User.Encourage(jiang.origin, User.Rank.Elite);

            //Console.WriteLine(origin);
            //Console.WriteLine(jiang.origin);//值传递，原值不变

            //  4、定义若干个publish()方法，可以发布求助，参数包括：
            //  title：标题，必填
            //  body：正文，可选，如果不填的话等同于title
            //  reward：悬赏帮帮币，可选，如果不填的话默认为10
            //方法最后控制台输出：
            //  发布文章：< title >
            //  内容为：< body >
            //  设置悬赏：< reward > 枚帮帮币

            //Problem problem = new Problem();
            //problem.Publish("一起帮", "互助", 20);
            //problem.Publish("一起帮");
            //problem.Publish("标题", 30);
            //problem.Publish("标题","互助");


            //5、声明方法GetAverage()，该方法能够接收任意多个float值，比如：GetAverage(98.5, 78.4, 65, 88.3)，返回参数之和的平均值
            //float avg = GetAverage(98.5f, 78.4f, 65f, 88.3f);
            //float avg = GetAverage(20.5f, 122.4f, 65f, 66.3f);

            //Console.WriteLine(avg); // 输出：82.55

            //  6、将源栈同学姓名，按座位装入二维数组students。             
            //String[][] students = new String[5][]
            //{
            //    new String[] { "张伟", "王芳", },
            //    new String[] { "王磊", "张敏",  "刘洋" },
            //    new String[] { "赵强", "周杰", "吴敏", "郑伟" },
            //    new String[] {"钱静", "孙磊", "周芳",},
            //    new String[] {"王伟" }
            //};

            //7、定义一个方法showMutrix()，用它能：
            //  按行输出存储在二维数组里的元素
            //  返回数组中共有多少个元素
            //调用该方法，传入输出作业6中的数组，输出源栈同学姓名
            //ShowMutrix(students); //调用方法，输出二维数组
            //Console.WriteLine($"一共{ShowMutrix(students)}个人");

            //8、用for循环创建一个n行m列的二维数组，元素值等于下标之和，如下所示：
            //0 1 2 3 4
            //1 2 3 4 5
            //2 3 4 5 6
            //3 4 5 6 7
            //并将其按行列输出到控制台。

            //int n = 4; //行数
            //int m = 5; //列数
            //int[][] array = new int[n][];           

            ////交错数组
            //for (int i = 0; i < n; i++)
            //{
            //    array[i] = new int[m];
            //    for (int j = 0; j < m; j++)
            //    {
            //        array[i][j] = i + j;
            //        Console.Write(i + j + " ");
            //    }
            //    Console.WriteLine(); //换行
            //}

            //调用方法，创建二维数组并输出
            //int[,] arrays=GetArray( 4 , 5); 
            // for(int i = 0; i < arrays.GetLength(0); i++)
            // {                
            //     for (int j = 0; j < arrays.GetLength(1); j++)
            //     {
            //         Console.Write(arrays[i, j] + " ");
            //     }
            //     Console.WriteLine(); //换行
            // }



            //面向对象:构造函数，抽象类 & 接口 
            //3、用最简单 / 优雅的方法，让：
            //Problem类可以在生成其对象时设定悬赏值。
            //Problem problem = new Problem();
            //Console.WriteLine(problem.Reward); 
            //所有Entity（及其子类）对象生成时，就能获得一个（累加的不重复）id
            //Entity entity = new Entity();
            //Entity entity1 = new Entity();

            //Console.WriteLine(entity.Id);
            //Console.WriteLine(entity1.Id);

            //Content content1 = new Content();
            //Content content2 = new Content();
            //Console.WriteLine(content1.Id);
            //Console.WriteLine(content2.Id);
            //每一个Content对象一定有Body赋值
            //Content content1 = new Content();
            //Content content2 = new Content();

            //Console.WriteLine(content2.Body);
            //Console.WriteLine(content1.Body);

            //4、声明一个令牌管理（TokenManager）类，利用之前学过的位运算：
            //使用私有的_tokens字段存储所具有的权限
            //暴露Add(Token)、Remove(Token)和Has(Token)方法，可以添加、删除和判断其有无某个权限
            //TokenManager是用于存储用户权限的，它怎么和User类关联呢？

            //User user = new User();
            //user.AddPermission(tokens.read);
            //user.AddPermission(tokens.write);

            //user.HasPermission(tokens.read); //检查是否有读权限
            //user.RemovePermission(tokens.read);

            //user.HasPermission(tokens.read); //检查是否有读权限
            //user.HasPermission(tokens.write); //检查是否有读权限

            //7、引入Message的两个子类EmailMessage和DBMessage，并让他们实现接口ISendMessage（其中含Send()方法声明）：

            //EmailMessage message = new EmailMessage();
            //message.Send();
            //DBMessage dbMessage = new DBMessage();
            //dbMessage.Send();


            //10、一起帮还可以在好友间发私信，所有又有了IChat接口，其中也有一个Send()方法（之前的Send()方法）声明。假设User类同时继承了ISendMessage和IChat，如何处理？ 
            //User user = new User();
            //ISendMessage sender = user; //通过接口引用调用Send方法
            //sender.Send();

            //IChat chat = user; //通过接口引用调用Send方法
            //chat.Send();

            //----------在学习完 Java和C#类库后完成 ----------
            //1、观察一起帮登录页面，用if...else ...完成以下功能。
            //用户依次由控制台输入：验证码、用户名和密码：
            //    如果验证码输入错误，直接输出：“*验证码错误”；
            //    如果用户名不存在，直接输出：“*用户名不存在”；
            //    如果用户名或密码错误，输出：“*用户名或密码错误”
            //    以上全部正确无误，输出：“恭喜！登录成功！”
            //PS：验证码 / 用户名 / 密码直接预设在源代码中，输入由控制台完成。



            //2、定义方法getRandom()，生成一个元素值随机，但从小到大排列的数组。通过参数控制
            //最小值 / 起始值（默认为0）
            //相邻元素间最大差值（默认为10）
            //元素个数（没有默认值）

            //int[] randomArray = GetRandom(5);
            //int[] randomArray = GetRandom(5,10);
            //int[] randomArray = GetRandom(7,5,20);
            //for (int i = 0; i < randomArray.Length; i++)
            //{
            //    Console.Write(randomArray[i] + " ");
            //} 


            //3、修改之前的GetAverage()，用户（调用方）能够要求返回的平均值：
            //向上 / 向下取整，
            //四舍五入保留若干位小数（默认，2位）
            //float[] scores = { 98.5f, 78.4f, 65f, 88.3f };

            // 测试各种调用方式
            //Console.WriteLine("默认调用(四舍五入保留2位): " +
            //GetAverage(scores));

            //Console.WriteLine("指定小数位数(保留3位): " +
            //                  GetAverage(3, scores).ToString("F3"));

            //Console.WriteLine("向上取整: " +
            //                  GetAverage(RoundingMethod.Ceiling, scores));

            //Console.WriteLine("向下取整: " +
            //                  GetAverage(RoundingMethod.Floor, scores));

            //Console.WriteLine("四舍五入保留1位: " +
            //                  GetAverage(RoundingMethod.Round, 1, scores));

            //Console.WriteLine("向上取整保留1位: " +
            //                  GetAverage(RoundingMethod.Ceiling, 1, scores));

            //4、定义一个类RandomArray，包含一个方法get()，能够通过：
            //构造函数传参
            //属性设值
            //的方式，实现和第2题一样的功能
            //RandomArray randomArray = new RandomArray(5, 10, 20); //创建一个RandomArray对象，传入参数
            //RandomArray randomArray = new RandomArray(6); //只传入数组长度，其他参数使用默认值
            //RandomArray randomArray = new RandomArray(5, 10); //传入数组长度和起始值，差值使用默认值
            //int[] array = randomArray.get(); //调用get()方法获取数组
            //for (int i = 0; i < array.Length; i++)
            //{
            //    Console.Write(array[i] + " "); //输出数组元素
            //}

            //5、完成“猜数字”游戏，方法名GuessMe()：
            //GuessMe(); //调用猜数字游戏方法

            //C#：面向过程第1题：利用可选参数重构之前作业getRandom()
            //int[] array= GetRandom(6);
            //int[] array = GetRandom(6, 10); //指定起始值为10
            //int[] array = GetRandom(6, 10, 20); //指定起始值为10，差值为20
            //for (int i = 0; i < array.Length; i++)
            //{
            //    Console.Write(array[i] + " ");
            //}

            //C#：面向过程第2题:两个同学的床位号分别用两个int变量存储，将其传入Swap()方法，就可以交换（利用ref调用） 
            //int jiang = 15; //第一个同学的床位号
            //int wang = 3; //第二个同学的床位号
            //Console.WriteLine($"jiang的床位是{jiang},黄的床位是{wang}");
            //swap(ref jiang, ref wang); //调用Swap方法交换床位号

            //C#：面向过程第3题:重构方法LogOn()，调用之后能够获得：
            //true / false，表示登陆是否成功
            //string，表示登陆失败的原因
            //LogOn(out bool logStatus, out string reason); //调用LogOn方法
            //Console.WriteLine($"登录结果: {logStatus}, 原因: {reason}");

            //C#面向对象类/索引器第1题
            //1、在之前作业的基础上，继续用代码和调试过程演示：
            //1、值类型参数的值传递
            // int original = 10;
            //Console.WriteLine($"调用前: {original}"); // 输出 10
            //ModifyValue(original);
            //Console.WriteLine($"调用后: {original}"); // 输出 10（未改变）

            //2、引用类型参数的值传递
            //int[] array = { 1, 2, 3 };
            //Console.WriteLine($"调用前[0]: {array[0]}"); // 输出 1
            //ModifyArray(array);
            //Console.WriteLine($"调用后[0]: {array[0]}"); // 输出 100（修改原始对象数据）

            //3、值类型参数的引用传递
            //int original = 10;
            //Console.WriteLine($"调用前: {original}"); // 输出 10
            //ModifyValueRef(ref original);
            //Console.WriteLine($"调用后: {original}"); // 输出 100(已改变)

            //4、引用类型参数的引用传递
            //int[] array = { 1, 2, 3 };
            //Console.WriteLine($"调用前[0]: {array[0]}"); // 输出 1
            //ModifyArrayRef(ref array);
            //Console.WriteLine($"调用后[0]: {array[0]}"); // 输出 4（修改了引用，原始对象指向了新数组）
            //TimeSpan span = new TimeSpan(2, 4, 12, 30, 0);
            //Console.WriteLine(span.Hours);
            //Console.WriteLine(span.TotalHours);

            //5、return代替引用类型的引用传递
            //int[] array = { 1, 2, 3 };
            //Console.WriteLine($"调用前[0]: {array[0]}"); // 输出 1
            //array = ModifyArrayReturn(array);
            //Console.WriteLine($"调用后[0]: {array[0]}"); // 输出 4（修改了引用，原始对象指向了新数组）

            //5、声明一个令牌（Token）枚举，包含值：SuperAdmin、Admin、Blogger、Newbie、Registered，然后改造之前的TokenManager类。
            //var manager = new TokenManager();

            //// 添加单个权限
            //manager.Add(Token.Admin);
            //Console.WriteLine(manager.Has(Token.Admin)); // 输出: True

            //// 分配角色（覆盖现有权限）
            //manager.AssignRole(Role.ContentTeam); // 权限: Admin | Blogger
            //Console.WriteLine(manager.Has(Token.Blogger)); // 输出: True

            //// 移除权限
            //manager.Remove(Token.Blogger);
            //Console.WriteLine(manager.Has(Token.Blogger)); // 输出: False

            //J&CObject
            //2、声明一个Article类（如果还没有的话），包含两个属性：Title和Body，重写equals()方法：只要两个对象Title和Body都相等，返回true；否则，false。 
            //Article atai = new Article();
            //Article baby = new Article();
            //atai.Title = "一起帮的文章";
            //baby.Title = "一起帮的文章";
            //atai.Body = "一起帮的内容";
            //baby.Body = "一起帮的内容";
            //Console.WriteLine(atai.Equals(baby)); //调用Article类的Equals方法

            //3、 调整Article的代码，使得当控制台输出一个Article对象的时候，输出的是它的标题和内容。
            //Article atai = new Article();
            //atai.Title = "一起帮的文章";
            //atai.Body = "一起帮的内容";
            //Console.WriteLine(atai.ToString());


            //4、构造一个能装任何数据的数组，并完成数据的读写
            //object[] objects = new object[5]; //声明一个object类型的数组
            //objects[0] = 123; //存储整数
            //objects[1] = "Hello"; //存储字符串
            //objects[2] = 45.67f; //存储浮点数
            //objects[3] = new DateTime(2023, 10, 1); //存储日期
            //objects[4] = new Article { Title = "一起帮的文章", Body = "一起帮的内容" }; //存储Article对象
            //for (int i = 0; i < 5; i++)
            //{
            //    Console.WriteLine(objects[i]);
            //}

            //5、使用object改造数据结构栈（MimicStack），并在出栈时获得出栈元素

            //MimicStack stack = new MimicStack(5); //创建一个容量为5的栈

            //stack.Push("Hello"); //入栈字符串
            //stack.Push(123); //入栈整数
            //stack.Push(45.67f); //入栈浮点数
            //stack.Push(new DateTime(2023, 10, 1)); //入栈日期
            //stack.Push(new Article { Title = "一起帮的文章", Body = "一起帮的内容" }); //入栈Article对象

            //for (int i = 0; i < stack.depth.Length; i++)
            //{
            //    Console.WriteLine(stack.depth[i]); //输出栈中的元素
            //}
            //Console.WriteLine("123");

            //J&C 异常
            //
            //1、修改之前的属性验证：problem.Reward为负数时直接抛出“参数越界”异常
            //Problem test = new Problem();
            //test.Reward=-5;
            //Console.WriteLine(test.Reward);

            //2、内容（Content）发布（Publish）的时候检查其作者（Author）是否为空，如果为空抛出“参数为空”异常
            //Suggest test =new Suggest();
            //test.Author = null; //故意设置为空，触发异常
            //test.Publish();

            //Problem test = new Problem();
            //test.Publish();

            //Article test = new Article();
            //test.Publish();

            //3、在ContentService中捕获异常
            //    如果是“参数为空”异常，控制台输出：内容的作者不能为空，将当前异常封装进新异常的InnerException，再将新异常抛出
            //    如果是“”参数越界”异常，控制台输出：求助的Reward为负数（-XX），不再抛出异常
            //ContentService test = new ContentService();
            //Problem problem = new Problem();
            //User user = new User();
            //problem.Author = user;           
            //test.Release(problem);
            //4、ContentService中无论是否捕获异常，均要控制台输出：XXXX年XX月XX日 XX点XX分XX秒（当前时间），请求发布内容（Id = XXX）
            //ContentService test = new ContentService();
            //Problem problem = new Problem();
            //User user = new User();
            //problem.Author = user;
            //test.Release(problem);          
            //5、在入口函数调用ContentService时，捕获一切异常，并记录（控制台输出）异常的消息和堆栈信息
            //ContentService test = new ContentService();
            //Problem problem = new Problem();
            //User user = new User();
            //problem.Author = user;
            //test.Release(problem);


            //J&C 泛型 
            //1、改造Entity类，让其Id可以为任意类型
            //2、声明一个泛型的Repository（仓库）类，可以存储任意Entity对象，在里面添加一个静态方法Load(id)，方法返回一个new出来的entity对象（模拟id返回对应的entity）
            // 步骤1：为实体类型注册工厂委托
            //Repository<User, int>.SetFactory(id => new User(id));

            //// 步骤2：调用Load方法
            //var user = Repository<User, int>.Load(123);
            //Console.WriteLine($"User ID: {user.Id}");
            //3、用泛型改造：
            //1、双向链表和MimicStack栈：存取元素类型扩展
            //var intStack = new MimicStack<int>(3);
            //intStack.Push(10);
            //intStack.Push(20);
            //Console.WriteLine(intStack.Pop());  // 输出 20
            //Console.WriteLine(intStack.Stored); // 输出 1

            //var stringStack = new MimicStack<string>(2);
            //stringStack.Push("Hello");
            //stringStack.Push("Generics");
            //Console.WriteLine(stringStack.Empty); // 输出 0 (栈已满)

            //2、取数组中最大值（提示：利用Comparable<T> 进行比较）
            //int[] intArray = { 3, 7, 8, 12, 23, 35, 46, 59, 70, 108 };
            //Console.WriteLine($"int数组最大值: {GetMax(intArray)}");
            //3、二分查找
            // 整型数组
            //int index1 = BinarySeek(intArray, 23); // 返回 4
            //Console.WriteLine(index1);
            // 字符串数组
            //string[] strArray = { "apple", "banana", "cherry", "date" };
            //int index2 = BinarySeek(strArray, "cherry"); // 返回 2[2](@ref)
            //Console.WriteLine(index2);

            //c#：Lambda表达式
            //  1、使用double做数据类型，分别用自定义的 / 内置的lambda，完成面向函数：Lamda中1 - 3题
            //      1、声明一个匿名函数，能够求两个参数的和，然后将其赋值给变量calculate
            //Console.WriteLine(calculate(1, 2)); 
            //内置lambda
            //Func<double, double, double> func = (a, b) => a + b;
            //Console.WriteLine(func(3, 5));

            //      2、给calculate用箭头函数重新赋值，让其能够求两个参数的差
            //calculate = (a, b) => a - b;
            //Console.WriteLine(calculate(5,20));
            //内置lambda
            // func = (a, b) => a - b;
            //Console.WriteLine(func(20, 5));

            //      3、声明一个命名函数merge，能够接受两个参数：一个数组numbers，一个回调函数calculate；
            //         然后merge()中调用calculate，将数组中相邻两个数进行运算（求和求差等），返回一个新数组。
            //double[] nums = { 12, 15, 20, 25, 30, 35 };
            //double[] newNums = Merge(nums, calculate);
            //foreach (var num in newNums)
            //{
            //    Console.Write(num + " "); // 输出新数组元素
            //}
            //内置lambda
            //double[] nums = { 12, 15, 20, 25, 30, 35 };
            //Func<double, double, double> sumFunc = (a, b) => a + b; // 定义求和的lambda表达式
            //double[] newNums = Merge(nums, sumFunc); // 使用求和的lambda表达式进行合并
            //foreach (var num in newNums)
            //{
            //    Console.Write(num + " "); // 输出新数组元素
            //}

            //2、改造Content的Publish()方法，使其能够接收lambda做参数，决定如何输出Content的标题和内容，比如：
            //    标题一行，内容一行：一共两行
            //    标题和内容之间只用冒号分割，不用两行
            //Article myArticle = new Article
            //{
            //    Title = "Hello Lambda",
            //    Body = "This is the body content."
            //};

            // 示例1: 标题一行，内容一行（默认行为，也可以通过lambda实现）
            //myArticle.Publish((title, body) =>$"{title}\n{body}");
            // 示例2: 标题和内容之间只用冒号分割，不用两行
            //myArticle.Publish((title, body) => $"{title}: {body}");

            //3、改造User的Login()方法，接收
            //    一个success参数，确定：登录成功之后如何处理
            //    一个failed参数，确定：登录失败如何处理
            //User user = new User();
            //        user.Login(
            //"admin",
            //"123456",
            //onSuccess: () =>
            //{
            //    Console.WriteLine("登录成功！跳转到主界面...");
            //    // this.Hide();
            //    // new MainForm().Show(); [1,5](@ref)
            //},
            //onFailed: (errorMsg) =>
            //{
            //    Console.WriteLine($"登录失败: {errorMsg}");
            //    // MessageBox.Show(errorMsg); [1](@ref)
            //}


            //J&C 反射
            //1、封装方法：

            //    GetPrivateField()，可以获得某对象的某私有字段值
            //    SetPrivateField()，可以修改某对象的某私有字段值
            //    提示：能不能用使用泛型？

            //Student student = new Student();
            //double fieldValue = student.GetPrivateField<double>("Score");
            //Console.WriteLine(fieldValue);

            //string fieldValue = student.GetPrivateField<string>("Name");
            //Console.WriteLine(fieldValue);

            //student.SetPrivateField("Score", 95.5);
            //double newScore = student.GetPrivateField<double>("Score");
            //Console.WriteLine(newScore);

            //student.SetPrivateField("Name", "李四");
            //string newName = student.GetPrivateField<string>("Name");
            //Console.WriteLine(newName);
            //2、自定义一个注解 / 特性HelpMoneyChanged（帮帮币变化）：
            //    该特性只能用于方法
            //    默认可以接受一个int类型的参数amount，表示帮帮币变化的数量
            //    有一个string类型的Message属性，记录帮帮币变化的原因
            //3、将HelpMoneyChanged应用于Publish()方法
            //4、用反射获取Publish()上的特性实例，输出其中包含的信息

            // 创建测试实例
            //var article = new Article
            //{
            //    //AuthorId = Guid.NewGuid(),
            //    HelpMoney = new HelpMoney() // 假设已实现HelpMoney类
            //};

            //// 调用Publish方法前，通过反射获取特性信息
            //MethodInfo publishMethod = typeof(Article).GetMethod("Publish", Type.EmptyTypes);
            //if (publishMethod != null)
            //{
            //    // 获取特性实例
            //    HelpMoneyChangedAttribute attribute = publishMethod.GetCustomAttribute<HelpMoneyChangedAttribute>();
            //    if (attribute != null)
            //    {
            //        // 输出特性信息
            //        Console.WriteLine($"帮帮币变化数量：{attribute.Amount}");
            //        Console.WriteLine($"变化原因：{attribute.Message}");
            //    }
            //}



            //J&C 字符串
            //1、确保文章（Article）的标题不能为null值，也不能为一个或多个空字符组成的字符串，而且如果标题前后有空格，也予以删除
            //Article article = new Article();
            //article.Title = "   一起帮的文章   ";
            //Console.WriteLine(ArticleTitle(article));

            //2、 设计一个适用的机制，能确保用户（User）的昵称（Name）不能含有admin、17bang、管理员等敏感词。
            //User user = new User();
            //user.SetName("admin");
            //Console.WriteLine(user.GetName());

            //3、确保用户（User）的密码（Password）：
            //    长度不低于6
            //    只能由大小写英语单词、数字和特殊符号（~!@#$%^&*()_+）三种字符组成，且每种字符至少包含一个
            //User user = new User();
            //user.SetPassword("123456@");

            //4、通过控制台读取用户输入，比如：3月，12周，100天，利用之前作业的GetDate()方法，输出指定时间段后的日期            
            //Console.WriteLine("请输入时间跨度（例如：3月、12周、100天），或指定基准日期（例如：@2024-03-15 3月）");
            //try
            //{
            //    string userInput = Console.ReadLine();
            //    DateTime resultDate = CheckTime.GetDate(userInput);

            //    Console.WriteLine($"计算结果为: {resultDate:yyyy-MM-dd HH:mm:ss dddd}");
            //}
            //catch (ArgumentException ex)
            //{
            //    Console.WriteLine($"错误: {ex.Message}");
            //}
            //catch (Exception ex)
            //{
            //    Console.WriteLine($"发生未知错误: {ex.Message}");
            //}
            //Console.WriteLine(CheckTime.GetDate());

            //5、不使用string自带的Join()方法，定义一个mimicJoin()方法，能将若干字符串用指定的分隔符连接起来，比如：mimicJoin("-", "a", "b", "c", "d")，其运行结果为：a - b - c - d
            //string[] arr = { "a", "b", "c", "d" };
            //Console.WriteLine(MimicJoin('-', arr));


            //6、实现GetCount(string container, string target)方法，可以统计出container中有多少个target
            //Console.WriteLine(GetCount("Hello, World! Hello, C#!Hello, python!", "Hello"));  //调用GetCount方法
            //String.Join("Hello", "World", "C#", "Python"); //调用String类的Join方法

            //7、在之前正则表达式作业 - 3的基础上，完成：
            //检查有无a标签（< a...> ...</ a >）的存在
            //string pattern = @"<a\s+[^>]*>[\s\S]*?<\/a>";
            //MatchCollection matches= Regex.Matches("<a href='http://www.17bang.org'>一起帮</a><a href='http://www.hao123.com'></a>", pattern);
            //foreach(Match m in matches)
            //{
            //    Console.WriteLine(m.Value);
            //}
            //如果有，找出其中的href属性（href = '...'中...的值） 
            //string html = @"
            //    <a href=""commonQuestion.html"">(｡ŏ_ŏ) 忘了</a>
            //    <a href='register.html'>注册</a>
            //    <a class='test' href=about.html>关于我们</a>
            //    <a nohref>无href属性</a>
            //    ";

            // 步骤1：匹配所有<a>标签
            //string aTagPattern = @"<a\s+[^>]*>[\s\S]*?</a>";
            //MatchCollection aTags = Regex.Matches(html, aTagPattern, RegexOptions.IgnoreCase);

            // 步骤2：提取每个<a>标签中的href值
            //string hrefPattern = @"href\s*=\s*([""']?)(.*?)\1";
            //Regex hrefRegex = new Regex(hrefPattern, RegexOptions.IgnoreCase);

            //foreach (Match aTag in aTags)
            //{
            //    Console.WriteLine("匹配到的a标签：" + aTag.Value);

            //    // 对当前a标签应用href提取正则
            //    Match hrefMatch = hrefRegex.Match(aTag.Value);
            //    if (hrefMatch.Success)
            //    {
            //        // Groups[2].Value 是href的值（第2个捕获组）
            //        Console.WriteLine("提取的href值：" + hrefMatch.Groups[2].Value);
            //    }
            //    else
            //    {
            //        Console.WriteLine("该a标签无href属性");
            //    }
            //    Console.WriteLine("------------------------");
            //}
            //控制台逐行输出：相邻 > 和 < 之间的内容            
            //string inputText = @"
            //        <h3 
            //        script  =""onclick:function(){}"">
            //     概念引入
            //        </h3>
            //        <img src= '/picture.jpg' alt='源栈logo' />
            //        <p style=""color:red;"">
            //     在程序中我们经常会遇到这样一种<strong>需求</strong>：当name=""飞哥""时 </p>
            //        ";
            //string textpattern = @"(?<=>)\s*([\s\S]*?)\s*(?=<)";
            //Regex textRegex = new Regex(textpattern, RegexOptions.IgnoreCase);

            //MatchCollection texts = textRegex.Matches(inputText);
            //foreach (Match text in texts)
            //{
            //    string content = text.Groups[1].Value;
            //    // 只输出非空内容
            //    if (!string.IsNullOrEmpty(content))
            //    {
            //        Console.WriteLine("匹配到的内容：" + content);
            //        Console.WriteLine("------------------------");
            //    }
            //}

            //将原字符串替换为只有7.2中的内容
            //StringBuilder sb = new StringBuilder();
            //这个有用
            //string pattern = @"href\s*=\s*(?:""(?<href>[^""]*)""|'(?<href>[^']*)'|(?<href>[^>\s]+))";
            //缺陷：无法匹配 href=about.html 这种没有引号的情况
            //string hrefPattern = @"href\s*=\s*([""']?)(.*?)\1";

            //MatchCollection texts = Regex.Matches(html, Pattern);
            //foreach (Match text in texts)
            //{
            //    string content = text.Groups[1].Value;
            //    // 只输出非空内容
            //    if (!string.IsNullOrEmpty(content))
            //    {
            //        sb.Append(content);
            //    }
            //}
            //Console.WriteLine("替换后的内容：" + sb.ToString().Trim());

            #region J&c集合
            //2、新建一个UserRepository，添加方法：
            //Save(user)：可以把user保存到仓库
            //GetByName(name)：可以根据用户名查找到某个用户
            //利用上述方法再次实现用户登录LogOn()，控制台输出三种可能的结果：
            //根据Name没有找到相应的用户：*用户名不存在
            //根据Name找到了相应的用户，但密码不对：*用户名或密码错误
            //信息正确无误：*成功登录

            //UserRepository userRepository = new UserRepository();
            //userRepository.Save(new User { Name = "alice", Password = "password@123" });
            //userRepository.Save(new User { Name = "bob", Password = "p@1234" });
            //userRepository.Save(new User { Name = "charlie", Password = "qwert@134" });
            //foreach (var user in userRepository)
            //{
            //    Console.WriteLine($"用户: {user.Name}, 密码: {user.Password}");
            //}

            //User user1 = userRepository.GetByName("bo");
            //Console.WriteLine(user1.Name + user1.Password);

            //User.Login(
            //    "bob",
            //    "p@123",
            //    onSuccess: () =>
            //    {
            //        Console.WriteLine("*成功登录");
            //        // this.Hide();
            //        // new MainForm().Show(); [1,5](@ref)
            //    },
            //    onFailed: (errorMsg) =>
            //    {
            //        Console.WriteLine($"登录失败: {errorMsg}");
            //        // MessageBox.Show(errorMsg); [1](@ref)
            //    }

            //);

            //4、在之前“文章 / 评价 / 评论 / 用户 / 关键字”对象模型的基础上，添加相应的数据，然后新建相应的repository类，利用Linq（C#）或Stream（Java）完成以下操作： 
            //User fg = new User { Name = "飞哥" };
            //User xy = new User { Name = "小鱼" };
            //User xw = new User { Name = "小王" };
            //User py = new User { Name = "皮皮" };

            //Keyword csharp = new Keyword { Text = "c#" };
            //Keyword java = new Keyword { Text = "Java" };
            //Keyword python = new Keyword { Text = "python" };
            //Keyword javaScript = new Keyword { Text = "javaScript" };
            //Keyword net = new Keyword { Text = ".Net" };

            //Comment comment1 = new Comment { Title = "挺好", Body = "good" };
            //Comment comment2 = new Comment { Title = "需要修改", Body = "建议123" };
            //Comment comment3 = new Comment { Title = "不太好", Body = "重新开始" };
            //Comment comment4 = new Comment { Title = "真好", Body = "继续努力" };
            //Comment comment5 = new Comment { Title = "加油", Body = "多学习" };

            //Article yz1 = new Article
            //(
            //    id: 1,
            //    createTime: new DateTime(2019, 5, 1)// 必须通过构造函数传 CreateTime
            //)
            //{
            //    Title = "标题1",
            //    Body = "内容1",
            //    Author = fg,
            //    KeyWords = new List<Keyword> { csharp },
            //    Comments = new List<Comment> { comment5, comment1,comment3 }

            //};

            //Article yz2 = new Article
            //(
            //    id: 2,
            //    createTime: new DateTime(2019, 6, 1)// 必须通过构造函数传 CreateTime
            //)
            //{
            //    Title = "标题2",
            //    Body = "内容2",
            //    Author = xw,
            //    KeyWords = new List<Keyword> { java, javaScript },
            //    Comments = new List<Comment> { comment1, comment3 }

            //};

            //Article yz3 = new Article
            //(
            //    id: 3,
            //    createTime: new DateTime(2019, 6, 1)// 必须通过构造函数传 CreateTime
            //)
            //{
            //    Title = "标题3",
            //    Body = "内容3",
            //    Author = xy,
            //    KeyWords = new List<Keyword> { python },
            //    Comments = new List<Comment> { comment2, comment4 }

            //};

            //Article yz4 = new Article
            //(
            //     id: 4,
            //    createTime: new DateTime(2019, 4, 1)
            //)
            //{
            //    Title = "标题4",
            //    Body = "内容4",
            //    Author = xy,
            //    KeyWords = new List<Keyword> { net },
            //    Comments = new List<Comment> { comment3 }

            //};

            //Article yz5 = new Article
            //(
            //    id: 3,
            //    createTime: new DateTime(2019, 6, 1)// 必须通过构造函数传 CreateTime
            //)
            //{
            //    Title = "标题5",
            //    Body = "csharp is good",
            //    Author = fg,
            //    KeyWords = new List<Keyword> { python, javaScript },
            //    Comments = new List<Comment> { comment4, comment5 }

            //};

            //IList<Article> articles = new List<Article>
            //{
            //   yz1,yz2,yz3,yz4,yz5
            //};


            //ArticleRepository ar = new ArticleRepository();
            //ArticleRepository.entities = articles;
            //1、找出“飞哥”发布的文章
            //var fgArticle = ar.GetArticlesByAuthorFeiGe();
            //foreach (var article in fgArticle)
            //{
            //    Console.WriteLine($"飞哥的文章: {article.Title}");
            //}
            //2、找出2019年4月21日以后“小鱼”发布的文章
            //var xyArticle=ar.GetArticlesByAuthorxy();
            //foreach (var article in xyArticle)
            //{
            //    Console.WriteLine($"小鱼的文章: {article.Title}, 发布时间: {article.CreateTime}");
            //}
            //3、按发布时间升序 / 降序排列显示文章
            //升序
            //var orderbyTime = ar.OrderbyTime();
            //foreach(var item in orderbyTime)
            //{
            //    Console.WriteLine($" 发布时间: {item.CreateTime},标题:{item.Title}，作者:{item.Author.Name}");
            //}

            //降序
            //var orderbyTimeDesc = ar.OrderbyDescend();
            //foreach (var item in orderbyTimeDesc)
            //{
            //    Console.WriteLine($" 发布时间: {item.CreateTime},标题:{item.Title}，作者:{item.Author.Name}");
            //}
            //4、统计每个用户各发布了多少篇文章
            //var groupbyAuthor = ar.GroupByAuthor();
            //foreach (var group in groupbyAuthor)
            //{
            //    Console.WriteLine($"作者：{group.Key.Name}，文章数量：{group.Count()}");
            //    foreach (var article in group) {
            //        Console.WriteLine($"- 文章：{article.Title}");
            //    }
            //}
            //5、找出包含关键字“C#”或“.NET”的文章
            //var keyarticles = ar.GetArticlesKeyword();
            //foreach (var article in keyarticles)
            //{
            //    Console.WriteLine($"包含关键字C#或.NET的文章: {article.Title}, 关键字: {string.Join(", ", article.KeyWords.Select(k => k.Text))}");
            //}
            //6、找出评论数量最多的文章
            //var keyarticles = ar.GetArticlesCountMost();
            //foreach (var article in keyarticles)
            //{
            //    Console.WriteLine($"评论数量最多的文章: {article.Title}, 评论数量: {article.Comments.Count}");
            //}

            //7、找出每个作者评论数最多的文章
            //var articlesGroup = ar.ArticlesComentMostGroup();
            //foreach( var article in articlesGroup)
            //{
            //    Console.WriteLine($"作者：{article.Author.Name},评论最多文章{article.Title}");
            //}
            //8、找出每个作者最近发布的一篇文章
            //var recentArticles = ar.RecentArticlesByAuthor();
            //foreach (var article in recentArticles)
            //{
            //    Console.WriteLine($"作者：{article.Author.Name}, 最近发布的文章：{article.Title}, 发布时间：{article.CreateTime}");
            //}
            //9、找出每一篇求助的悬赏都大于5个帮帮币的求助作者
            //Problem pr1 =new Problem()
            //{ 
            //    Reward=6,
            //    Title="标题1",
            //    Author=fg,
            //};

            //Problem pr2 = new Problem()
            //{
            //    Reward = 8,
            //    Title = "标题2",
            //    Author = fg,
            //};

            //Problem pr3 = new Problem()
            //{
            //    Reward = 6,
            //    Title = "标题3",
            //    Author = xy,
            //};

            //Problem pr4 = new Problem()
            //{
            //    Reward = 5,
            //    Title = "标题4",
            //    Author = xw,
            //};

            //Problem pr5 = new Problem()
            //{
            //    Reward = 9,
            //    Title = "标题5",
            //    Author = xy,
            //};

            //IList<Problem> problems = new List<Problem>
            //{
            //   pr1,pr2,pr3,pr4,pr5
            //};

            //ProblemRepository ar = new ProblemRepository();
            //ProblemRepository.entities = problems;

            //var problemByAuthors = ar.GetRewardAuthor();
            //foreach (var authors in problemByAuthors)
            //{
            //    Console.WriteLine($"每一篇求助的悬赏都大于5个帮帮币的求助作者: {authors.Name}");
            //}
            #endregion

            #region j&C多线程

            //1、Task和Thread的区别

            //task
            //Console.WriteLine("准备起床，开始");
            //Action<int> getup = (i) =>
            //{
            //    Console.WriteLine($"起床 {i}");
            //};

            //for (int i = 0; i < 5; i++)
            //{
            //    //Task t1 = Task.Run(() => { getup(i); });
            //    //t1.Wait(); // 等待任务完成

            //    int temp = i; // 关键：创建局部变量副本
            //    Task task = Task.Run(() => { getup(temp); }); // 捕获临时变量 temp
            //}
            //Console.WriteLine("起床了，结束");

            //Thread
            //Console.WriteLine("开始");
            //for (int i=0;i<5;i++)
            //{
            //    Console.WriteLine($"主线程: {i}");
            //    Thread.Sleep(100); // 模拟一些工作
            //}
            //Thread t2 = new Thread(() =>
            //{
            //    Console.WriteLine("Thread t2 is running...");
            //});
            //Thread t3 = new Thread(() =>
            //{
            //    Console.WriteLine("Thread t3 is running...");
            //});
            //Console.WriteLine("结束了");
            //t3.IsBackground = true;
            //t3.Start();
            //t2.IsBackground = true; // 设置为后台线程
            //t2.Start();





            //2、Wait()和await的区别

            //await
            //Outprocess();
            //for (int i = 0; i < 5; i++)
            //{
            //    Console.WriteLine($"主线程: {i}");
            //    Thread.Sleep(100); // 模拟一些工作
            //}

            //wait()


            //WaitProcess();
            //for (int i = 0; i < 5; i++)
            //{
            //    Console.WriteLine($"主线程: {i}");
            //    Thread.Sleep(100); // 模拟一些工作
            //}
            //Console.WriteLine("任务t1完成，主线程继续执行。");
            #endregion

            #region j&CIO

            //1、现有一个email.txt文件，里面存放了若干email地址，使用分号（;）或者换行进行了分隔。请
            //    1、删除其中重复的email地址，
            //    2、并按每30个email一行（行内用; 分隔）重新组织生成newEmail.txt
            //string inputFile = @"F:\17bang\email.txt";
            //string outputFile = @"F:\17bang\newEmail.txt";
            //ProcessEmailFile(inputFile, outputFile);
            //2、随机生成不同颜色的、包含干扰线条和点的验证码图片（注意：当你在循环中使用随机，有可能会出现一些你意想不到的事情，请查阅资料先予以解决）
            // 1. 生成随机验证码字符串（例如4位）
            //string captchaText = Captcha.GenerateRandomCode(4);
            //Console.WriteLine($"生成的验证码: {captchaText}");

            //// 2. 根据字符串生成验证码图片
            //byte[] imageBytes = Captcha.CreateCaptchaImage(captchaText);

            //// 3. 将图片保存为文件（也可用于网络响应）
            //string filePath = @"F:\17bang\captcha.jpg";
            //File.WriteAllBytes(filePath, imageBytes);
            //Console.WriteLine($"验证码图片已保存至: {Path.GetFullPath(filePath)}");

            //3、将第2题代码进行重构，封装在类Captcha中（仔细考虑应该封装什么暴露什么，应该如何进行方法拆分等），并为其添加异常机制，要求能够：
            //    显式的抛出一个自定义异常
            //    捕获并包裹一个被抛出的异常，记入日志文件，然后再次抛出
            //    根据不同的异常，给用户相应的友好的异常提示（控制台输出）
            //    注意释放文件资源
            //var generator = new Captcha();

            //try
            //{
            //    // 1. 生成随机验证码字符串
            //    string captchaText = generator.GenerateRandomCode(4);
            //    Console.WriteLine($"生成的验证码: {captchaText}");

            //    // 2. 根据字符串生成验证码图片
            //    byte[] imageBytes = generator.CreateCaptchaImage(captchaText);

            //    // 3. 将图片保存为文件
            //    string filePath = @"F:\17ban\captcha2.jpg"; 
            //    generator.SaveCaptchaImage(imageBytes, filePath);
            //    Console.WriteLine($"验证码图片已保存至: {Path.GetFullPath(filePath)}");
            //}
            //catch (CaptchaGenerationException ex)
            //{
            //    Console.WriteLine($"验证码生成错误: {ex.Message}");
            //    Console.WriteLine("请检查输入参数或联系技术支持");
            //}
            //catch (Exception ex)
            //{
            //    Console.WriteLine($"发生未处理的异常: {ex.Message}");
            //    Console.WriteLine("请联系技术支持");
            //}

            #endregion

        }





        //这里是作业的内容，包含了方法的实现，
        //5、声明方法GetAverage()，该方法能够接收任意多个float值，比如：GetAverage(98.5, 78.4, 65, 88.3)，返回参数之和的平均值
        //public static float GetAverage(params float[] scores)
        //{
        //    float sum = 0;
        //    foreach (float score in scores)
        //    {
        //        sum += score;
        //    }
        //    return sum / scores.Length;
        //}

        //  7、定义一个方法showMutrix()，用它能：
        //  按行输出存储在二维数组里的元素
        //  返回数组中共有多少个元素
        //调用该方法，传入输出作业6中的数组，输出源栈同学姓名
        //public static int ShowMutrix(string[][] students)
        //{
        //    int count = 0; //计数器
        //    for (int i = 0; i < students.Length; i++)
        //    {
        //        string[] student = students[i];
        //        for (int j = 0; j < student.Length; j++)
        //        {
        //            Console.Write(student[j] + " ");
        //            count++; //计数器加1
        //        }
        //        Console.WriteLine();//换行
        //    }
        //    return count; //返回计数器的值
        //}

        //8、用for循环创建一个n行m列的二维数组，元素值等于下标之和，如下所示：
        //并将其按行列输出到控制台。
        //public static int[,] GetArray(int n, int m)
        //{           
        //    private int[,] array = new int[n, m];
        //    for (int i = 0; i < n; i++) 
        //    {
        //        for (int j = 0; j < m; j++)
        //        {
        //            array[i, j] = i + j; //元素值等于下标之和                   
        //        }
        //    }
        //    return array; //返回创建的二维数组
        //}


        //j&c 字符串第5题
        //public static string MimicJoin(char separator, String[] value)
        //{

        //    StringBuilder sb = new StringBuilder();
        //    for (int i = 0; i < value.Length; i++)
        //    {
        //        sb.Append(value[i]);
        //        sb.Append(separator);
        //    }

        //    return sb.ToString();
        //}

        //j&c 字符串第6题
        //public static int GetCount(string container, string target)
        //{
        //    return Regex.Matches(container, Regex.Escape(target)).Count;
        //}


        //j&c 字符串第1题
        //public static string ArticleTitle(Article article)
        //{
        //    if (string.IsNullOrEmpty(article.Title))
        //    {
        //        throw new ArgumentException("标题不能为空或仅包含空白字符。");
        //    }
        //    return article.Title.Trim();
        //}




        //j&c面向对象 c#第2题
        // 方法重载1：只指定数组长度
        //public static int[] GetRandom(int count)
        //{
        //    return GetRandom(count, 0, 10);
        //}

        //// 方法重载2：指定数组长度和起始值
        //public static int[] GetRandom(int count, int minvalue)
        //{
        //    return GetRandom(count, minvalue, 10);
        //}

        //static int[] GetRandom(int count, int minvalue, int difference)
        //{
        //    if (count <= 0)
        //        throw new ArgumentException("数组长度必须大于0", nameof(count));

        //    if (difference <= 0)
        //        throw new ArgumentException("差值范围必须大于0", nameof(difference));


        //    Random random = new Random();
        //    int[] randomArray = new int[count]; //创建一个指定长度的数组
        //    randomArray[0] = minvalue;          //设置第一个元素为起始值
        //    int sum = minvalue; //初始化和为起始值           

        //    for (int i = 1; i < count; i++)
        //    {
        //        randomArray[i] = random.Next(sum, sum + difference); //生成1到100之间的随机数
        //        sum = randomArray[i];
        //    }
        //    return randomArray;
        //}




        //j&c面向对象 c#第3题
        /// <summary>
        /// 取整，四舍五入枚举
        /// </summary>
        //internal enum RoundingMethod
        //{
        //    Floor,
        //    Ceiling,
        //    Round
        //}

        //public static double GetAverage(params float[] scores)
        //{
        //    return GetAverage(RoundingMethod.Round, 2, scores);
        //}

        //public static double GetAverage(int decimalPlaces, params float[] scores)
        //{
        //    return GetAverage(RoundingMethod.Round, decimalPlaces, scores);
        //}

        //public static double GetAverage(RoundingMethod method, params float[] scores)
        //{
        //    return GetAverage(method, (method == RoundingMethod.Round) ? 2 : 0, scores);
        //}


        //public static double GetAverage(RoundingMethod method, int decimalPlaces, params float[] scores)
        //{
        //    if (scores == null || scores.Length == 0)
        //        return double.NaN; // 处理空数组情况

        //    float sum = 0;
        //    foreach (float score in scores)
        //    {
        //        sum += score;
        //    }

        //    // 计算平均值
        //    double average = sum / scores.Length;
        //    double factor = Math.Pow(10, decimalPlaces);

        //    switch (method)
        //    {
        //        case RoundingMethod.Floor:
        //            return Math.Floor(average * factor) / factor;
        //        case RoundingMethod.Ceiling:
        //            return Math.Ceiling(average * factor) / factor;
        //        case RoundingMethod.Round:
        //        default:
        //            return Math.Round(average, decimalPlaces);
        //    }
        //}        


        //5、完成“猜数字”游戏，方法名GuessMe()：
        //随机生成一个大于0小于1000的整数
        //用户输入一个猜测值，系统进行判断，告知用户猜测的数是“大了”，还是“小了”
        //没猜中可以继续猜，但最多不能超过10次
        //    如果5次之内猜中，输出：你真牛逼！
        //    如果8次之内猜中，输出：不错嘛！
        //    10次还没猜中，输出：(～￣(OO)￣)ブ
        //public static void GuessMe()
        //{
        //    // 生成1到999之间的随机数
        //    Random random = new Random();
        //    int secretNumber = random.Next(1, 1000);
        //    int attempts = 0;
        //    const int maxAttempts = 10;

        //    Console.WriteLine("欢迎来到猜数字游戏！");
        //    Console.WriteLine($"我已经想好了一个1到999之间的数字，你有{maxAttempts}次机会猜出它。");

        //    while (attempts < maxAttempts)
        //    {
        //        attempts++;
        //        Console.Write($"第{attempts}次尝试，请输入你的猜测: ");

        //        // 读取用户输入并验证
        //        if (!int.TryParse(Console.ReadLine(), out int guess))
        //        {
        //            Console.WriteLine("请输入有效的整数！");
        //            attempts--; // 无效输入不计入尝试次数
        //            continue;
        //        }//else nothing

        //        // 检查猜测结果
        //        if (guess == secretNumber)
        //        {
        //            // 根据尝试次数给出不同反馈
        //            if (attempts <= 5)
        //            {
        //                Console.WriteLine("你真牛逼！");
        //            }
        //            else if (attempts <= 8)
        //            {
        //                Console.WriteLine("不错嘛！");
        //            }
        //            else
        //            {
        //                Console.WriteLine("恭喜猜对了！");
        //            }
        //            return; // 游戏结束
        //        }
        //        else if (guess < secretNumber)
        //        {
        //            Console.WriteLine("小了！");
        //        }
        //        else
        //        {
        //            Console.WriteLine("大了！");
        //        }
        //    }

        //    // 10次尝试都失败
        //    Console.WriteLine($"(～￣(OO)￣)ブ 游戏结束！正确答案是: {secretNumber}");
        //}

        //c# 面向过程第1题
        //static int[] GetRandom(int count,  int minvalue =0,  int difference=10)
        //{
        //    if (count <= 0)
        //        throw new ArgumentException("数组长度必须大于0", nameof(count));

        //    if (difference <= 0)
        //        throw new ArgumentException("差值范围必须大于0", nameof(difference));


        //    Random random = new Random();
        //    int[] randomArray = new int[count]; //创建一个指定长度的数组
        //    randomArray[0] = minvalue;          //设置第一个元素为起始值
        //    int sum = minvalue; //初始化和为起始值           

        //    for (int i = 1; i < count; i++)
        //    {
        //        randomArray[i] = random.Next(sum, sum + difference); //生成1到100之间的随机数
        //        sum = randomArray[i];
        //    }
        //    return randomArray;
        //}

        //c# 面向过程第2题
        //private static void swap(ref int jiang, ref int wang)
        //{
        //   int temp = jiang; //临时变量存储第一个同学的床位号
        //    jiang = wang; //将第二个同学的床位号赋值给第一个同学
        //    wang = temp; //将临时变量的值赋值给第二个同学
        //    Console.WriteLine($"交换后的床位号：jiang同学的床位号是{jiang}，wang同学的床位号是{wang}");
        //}

        //C# 面向过程第3题       
        //private static void LogOn(out bool log, out string failedseason)
        //{
        //    string correctCaptcha = "8A3B"; //预设验证码

        //    // 初始化out参数（必须确保所有路径都有赋值）
        //    log = false;
        //    failedseason = "";

        //    // 预设两组合法用户（用户名+对应密码）
        //    string validUser1 = "张三";
        //    string validPwd1 = "zhangsan123";

        //    string validUser2 = "李四";
        //    string validPwd2 = "lisi456";

        //    //  2. 第一步：验证验证码
        //    Console.Write("请输入验证码：");
        //    string inputCaptcha = Console.ReadLine();

        //    if (inputCaptcha != correctCaptcha)
        //    {
        //        failedseason = "*验证码错误";
        //        log = false; //登录失败               
        //        return;
        //    } //else nothing

        //    // 3. 第二步：验证用户名
        //    Console.Write("请输入用户名：");
        //    string inputUsername = Console.ReadLine();

        //    // 判断用户名是否存在
        //    if (inputUsername != validUser1 && inputUsername != validUser2)
        //    {
        //        // 用户名不存在

        //        failedseason = "*用户名不存在";
        //        log = false; //登录失败
        //        return;
        //    }//else nothing

        //        Console.Write("请输入密码：");
        //        string inputPassword = Console.ReadLine();

        //        if (
        //            (inputUsername == validUser1 && inputPassword == validPwd1) ||
        //            (inputUsername == validUser2 && inputPassword == validPwd2)
        //        )
        //        {
        //            Console.WriteLine("恭喜！登录成功！");
        //            log = true;
        //            failedseason = "登录成功";
        //        }
        //        else
        //        {
        //            // 密码错误
        //            failedseason = "*密码错误";
        //            log = false;                   
        //        }

        //C# 面向对象类/索引器第1题
        //static void ModifyValue(int num)
        //{
        //    num = 100; // 修改副本
        //    Console.WriteLine($"方法内: {num}"); // 输出 100
        //}

        // 引用类型参数的值传递示例
        //static void ModifyArray(int[] arr)
        //{
        //    arr[0] = 100; // 修改原始对象的数据
        //    Console.WriteLine($"方法内[0]: {arr[0]}"); // 输出 100

        //    arr = new int[] { 4, 5, 6 }; // 重新分配引用（只影响副本）
        //    Console.WriteLine($"方法内新数组[0]: {arr[0]}"); // 输出 4
        //}

        //值类型的引用传递示例
        //static void ModifyValueRef(ref int num)
        //{
        //    num = 100;
        //    Console.WriteLine($"方法内: {num}");
        //}

        //引用类型的引用传递示例
        //static void ModifyArrayRef(ref int[] arr)
        //{
        //    arr[0] = 100; // 修改原始对象的数据
        //    Console.WriteLine($"方法内[0]: {arr[0]}"); // 输出 100

        //    arr = new int[] { 4, 5, 6 }; // 重新分配引用（只影响副本）
        //    Console.WriteLine($"方法内新数组[0]: {arr[0]}"); // 输出 4
        //}

        //5、return代替引用类型的引用传递
        //static int[] ModifyArrayReturn(int[] arr)
        //{
        //    arr[0] = 100; // 修改原始对象的数据
        //    Console.WriteLine($"方法内[0]: {arr[0]}"); // 输出 100

        //    Console.WriteLine($"重新指向新数组"); 
        //    return new int[] { 4, 5, 6 }; // 重新分配引用（只影响副本）
        //}

        //3、用泛型改造：
        //双向链表和MimicStack栈：存取元素类型扩展
        //取数组中最大值（提示：利用Comparable<T> 进行比较）
        //public static T GetMax<T>(T[] ids) where T : IComparable<T>
        //{
        //    T max = ids[0];
        //    for (int i = 1; i < ids.Length; i++)
        //    {
        //        int cmp = max.CompareTo(ids[i]);
        //        if (cmp < 0)
        //        {
        //            max = ids[i];
        //        } //else nothing;
        //    }
        //    return max;
        //}
        //二分查找

        //public static int BinarySeek<T>(T[] array, T target) where T : IComparable<T>
        //{
        //    //int[] array = [3, 7, 8, 12, 23, 35, 46, 59, 70, 108];
        //    int left = 0;
        //    int right = array.Length;

        //    while (left < right)
        //    {
        //        int i = left + (right - left) / 2; // 防溢出计算中点[2](@ref)
        //        int cmp = target.CompareTo(array[i]); // 使用CompareTo比较[7](@ref)
        //        if (cmp > 0)       // target > array[i]
        //            left = i + 1;
        //        else if (cmp < 0)  // target < array[i]
        //            right = i;
        //        else               // 找到目标
        //            return i;
        //    }
        //    return -1; // 未找到
        //}

        //使用double做数据类型，分别用自定义的 / 内置的lambda，完成面向函数：Lamda中1 - 3题
        //1、声明一个匿名函数，能够求两个参数的和，然后将其赋值给变量calculate
        //delegate double Calculate(double a, double b);
        //static Calculate calculate = (a, b) => a + b;
        //2、给calculate用箭头函数重新赋值，让其能够求两个参数的差
        //3、声明一个命名函数merge，能够接受两个参数：一个数组numbers，一个回调函数calculate；
        //   然后merge()中调用calculate，将数组中相邻两个数进行运算（求和求差等），返回一个新数组。
        //相加相邻的两个数
        //delegate double Calculate(double a, double b);
        //static Calculate calculate = (front, back) => front + back;
        //static double[] Merge(double[] numbers, Calculate calculate)
        //{
        //    //double[] nums = {10,15,20,25,30,35 };
        //    double[] nums = new double[numbers.Length];//新数组
        //    //int index = 0;//新数组下标

        //    for (int i = 0; i < numbers.Length; i++)
        //    {
        //        if (i < numbers.Length - 1)
        //        {
        //            nums[i] = calculate(numbers[i], numbers[i + 1]);
        //        } //else nothing;
        //    }
        //    return nums;
        //}

        //内置lambda
        //1、声明一个匿名函数，能够求两个参数的和，然后将其赋值给变量calculate
        //2、给calculate用箭头函数重新赋值，让其能够求两个参数的差
        //3、声明一个命名函数merge，能够接受两个参数：一个数组numbers，一个回调函数calculate；
        //   然后merge()中调用calculate，将数组中相邻两个数进行运算（求和求差等），返回一个新数组。
        //相加相邻的两个数
        //delegate double Calculate(double a, double b);
        //static Calculate calculate = (front, back) => front + back;
        //static double[] Merge(double[] numbers, Calculate calculate)
        //{
        //    //double[] nums = {10,15,20,25,30,35 };
        //    double[] nums = new double[numbers.Length];//新数组
        //                                               //int index = 0;//新数组下标

        //    for (int i = 0; i < numbers.Length; i++)
        //    {
        //        if (i < numbers.Length - 1)
        //        {
        //            nums[i] = calculate(numbers[i], numbers[i + 1]);
        //        } //else nothing;
        //    }
        //    return nums;
        //}

        //内置lambda
        //static double[] Merge(double[] numbers, Func<double,double,double> sumFunc)
        //{
        //    // 空值检查：避免输入null时抛出异常
        //    if (numbers == null)
        //        throw new ArgumentNullException(nameof(numbers), "输入数组不能为null");

        //    // 边界处理：若数组长度≤1，无需合并，返回空数组
        //    if (numbers.Length <= 1)
        //        return Array.Empty<double>();

        //    // 新数组长度为原数组长度-1（相邻元素合并后减少一个元素）
        //    double[] result = new double[numbers.Length-1];//新数组
        //    for (int i = 0; i < numbers.Length; i++)
        //    {
        //        if (i < numbers.Length - 1)
        //        {
        //            // 计算当前元素与下一个元素的结果
        //            result[i] = sumFunc(numbers[i], numbers[i + 1]);
        //        } //else nothing;
        //    }
        //    return result;
        //}

        //J&C 反射
        //1、封装方法：

        //    GetPrivateField()，可以获得某对象的某私有字段值
        //    SetPrivateField()，可以修改某对象的某私有字段值
        //    提示：能不能用使用泛型？





        //public double SetPrivateField()
        //{
        //    Type typeinfo = typeof(Student);
        //    object student = typeinfo.GetConstructor(Type.EmptyTypes).Invoke(null);
        //    var scoreProperty = typeinfo.GetProperty("Score", BindingFlags.NonPublic | BindingFlags.Instance);
        //    if (scoreProperty != null)
        //    {
        //        // 注意Score是double类型，这里转换为int返回（根据实际需求调整）
        //        return (double)scoreProperty.GetValue(student);
        //    }
        //    return 0;
        //}

        //static T GetPrivateField<T>() where T : class 
        //{
        //    return null;
        //}

        //J&C 多线程
        //Wait()和await的区别 
        //static async void Outprocess()
        //{
        //    Console.WriteLine("第一层异步");
        //    await Process();

        //}


        //static async Task Process()
        //{
        //    Console.WriteLine("第二层异步");
        //    await Task.Run(() =>
        //    {
        //        Thread.Sleep(1);
        //        for (int i = 0; i < 5; i++)
        //        {
        //            Console.WriteLine($"async processing {i} with thread({Thread.CurrentThread.ManagedThreadId})...");
        //        }
        //    });

        //    for (int j = 0; j < 5; j++)
        //    {
        //        Console.WriteLine($"after await {j} with thread({Thread.CurrentThread.ManagedThreadId})...");
        //    }
        //}

        //static void WaitProcess()
        //{
        //    Console.WriteLine("第一层等待");
        //    Task t1 = Task.Run(() =>
        //    {
        //        Thread.Sleep(1);
        //        for (int i = 0; i < 5; i++)
        //        {
        //            Console.WriteLine($"wait processing {i} with thread({Thread.CurrentThread.ManagedThreadId})...");
        //        }
        //    });
        //    t1.Wait(); // 等待任务完成

        //    for (int j = 0; j < 5; j++)
        //    {
        //        Console.WriteLine($"after wait {j} with thread({Thread.CurrentThread.ManagedThreadId})...");
        //    }
        //}

        //J&C IO
        //static void ProcessEmailFile(string inputPath, string outputPath)
        //{
        //    //1、去重
        //    HashSet<string> uniqueEmails = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
        //    using (StreamReader reader = File.OpenText(inputPath))
        //    {
        //        string line;
        //        while ((line = reader.ReadLine()) != null)
        //        {
        //            // 分割每行中的电子邮件地址（支持分号分隔）
        //            string[] emailsInLine = line.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

        //            foreach (string email in emailsInLine)
        //            {
        //                string trimmedEmail = email.Trim();

        //                if (!string.IsNullOrEmpty(trimmedEmail))
        //                {
        //                    uniqueEmails.Add(trimmedEmail);
        //                }
        //            }
        //        }
        //    }

        //    // 2. 将去重后的电子邮件地址转换为列表
        //    List<string> emailList = uniqueEmails.ToList();

        //    using (StreamWriter writer = File.CreateText(outputPath))
        //    {
        //        for (int i = 0; i < emailList.Count; i += 30)
        //        {
        //            // 获取当前批次的30个电子邮件（或剩余的所有电子邮件）
        //            var batch = emailList.Skip(i).Take(30);
        //            // 用分号连接并写入文件
        //            string line = string.Join(";", batch);
        //            writer.WriteLine(line);
        //        }
        //    }
        //}
    }

}



